﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;


    /// <summary>
    /// A class to keep track of different showtimes and which ReservedSeatsList corresponds to the showtime.
    /// A new entry is to be added to the dictionary every time a new showtime is made. (Or at least when it is accessed by a customer.)
    /// </summary>
    public class GetReservedSeatsList
    {
        private static GetReservedSeatsList _instance;
        //private GetReservedSeatsList(){}

        public static GetReservedSeatsList Instance
        {
            get
            {
                if (_instance == null)
                {
                    _instance = new GetReservedSeatsList();
                }
                return _instance;
            }
        }

        private Dictionary<ShowTime, ReservedSeatsList> seatsDict = new Dictionary<ShowTime, ReservedSeatsList>();

        public ReservedSeatsList GetInternalSeats(ShowTime showTime)
        {

            //RemoveOld();
            ReservedSeatsList ret;
            //If date and room are the same, we can assume it's the right showtime. 
            //If it's not found, add a new one.
            if (seatsDict.Any(x => (x.Key.CinemaRoom.Id == showTime.CinemaRoom.Id 
                && x.Key.DateTime == showTime.DateTime)))
            {
                ret = seatsDict.Single(x => (x.Key.CinemaRoom.Id == showTime.CinemaRoom.Id 
                    && x.Key.DateTime == showTime.DateTime)).Value;
            }
            else
            {
                ret = new ReservedSeatsList(showTime);
                AddInternalSeats(showTime, ret);
            }
            return ret;
        }

        public void AddInternalSeats(ShowTime showTime, ReservedSeatsList reservedSeatsList)
        {
            seatsDict.Add(showTime, reservedSeatsList);
        }

        public void AddInternalSeats(ShowTime showTime)
        {
            seatsDict.Add(showTime, new ReservedSeatsList(showTime));
        }

        public void RemoveInternalSeats(ShowTime showTime)
        {
            //Only remove objects from the dictionary if they can no longer be used.
            if (showTime.DateTime < DateTime.Now)
            {
                //Even though the references might not be exactly the same, we still want to remove the ReservedSeatsList
                //Therefore it is assumed we can remove it, if the key shares the same DateTime and CinemaRoom, as these two properties makes a showtime unique.
                seatsDict.Remove(
                    seatsDict.Single(x => x.Key.DateTime == showTime.DateTime && x.Key.CinemaRoom == showTime.CinemaRoom).Key);
            }
        }

        //There's no point in keeping lists for showtimes that are already expired!
        private void RemoveOld()
        {
            try
            {
                if (seatsDict.Any(x => x.Key.DateTime > DateTime.Now))
                {
                    seatsDict.Remove(seatsDict.Single(x => (x.Key.DateTime.Ticks > DateTime.Now.Ticks)).Key);
                }
            }
            catch (Exception)
            {
                throw;
            }
        }
    }

